home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Frameworks
/
Sprocket Framework DR2
/
Sprocket Framework
/
DialogWindow.cp
< prev
next >
Wrap
Text File
|
1996-06-15
|
8KB
|
320 lines
/*
File: DialogWindow.cp
Project: Sprocket Framework 1.1 (DR2), released 6/15/96
Contains: Sub-class of TWindow to handle dialogs
To Do: ?
Sprocket Major Contributors:
----------------------------
Dave Falkenburg, producer of Sprocket 1.0
Bill Hayden, producer of Sprocket 1.1
Steve Sisak, producer of the upcoming Sprocket 2.0
Pete Alexander Steve Falkenburg Randy Thelen
Eric Berdahl Nitin Ganatra Chris K. Thomas
Marshall Clow Dave Hershey Leonard Rosenthal
Tim Craycroft Dave Mark Dean Yu
David denBoer Gary Powell
Cameron Esfahani Jon Summers Apple Computer, Inc.
Comments, Additions, or Corrections:
------------------------------------
Bill Hayden, Nikol Software <nikol@codewell.com>
*/
#include "Sprocket.h"
#include "UDialog.h"
#include "DialogWindow.h"
#include <Traps.h>
TDialogWindow::TDialogWindow(DialogTemplateID dialogTemplateID)
{
fTemplateID = dialogTemplateID;
fIsDialogWindow = true;
}
WindowRef TDialogWindow::MakeNewWindow(WindowRef behindWindow)
{
return GetDialogWindow ( GetNewDialog(fTemplateID, nil, (WindowRef) behindWindow));
}
Boolean TDialogWindow::Close(void)
{
Boolean retVal = TWindow::Close ();
// We have to do this in case we are the last window open
// We don't want to leave the menu items enabled
if ( retVal )
{
gMenuBar->EnableCommand ( cCut, false );
gMenuBar->EnableCommand ( cCopy, false );
gMenuBar->EnableCommand ( cPaste, false );
gMenuBar->EnableCommand ( cClear, false );
gMenuBar->EnableCommand ( cSelectAll, false );
OSErr err = gMenuBar->HiliteMenusForModalDialog(true);
if (err)
ErrorReporter(err, __FILE__, __LINE__);
}
return retVal;
}
////////////////////////////////////////////////////////////////////////////////////
//
// EventFilter strategy for Dialog Window
//
// Because of the need to patch and unpatch FrontWindow when calling IsDialogEvent
// and DialogSelect, only do these things when a Modeless Dialog is the frontmost
// window. (e.g., it’s event filter is active)
//
// NOTE: We always pass events through, except when an item has been hit.
//
// You may be thinking that it is easier to just rewrite the Dialog Manager in
// this program. You’re probably right.
pascal WindowRef FrontWindowPatchForDialogs();
pascal WindowRef
FrontWindowPatchForDialogs()
{
return FrontNonFloatingWindow();
}
#define uppFrontWindowPatchProcInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(WindowRef))))
UniversalProcPtr FrontWindowPatchUPP
= (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) &FrontWindowPatchForDialogs,uppFrontWindowPatchProcInfo,GetCurrentISA());
Boolean TDialogWindow::EventFilter(EventRecord *theEvent)
{
GrafPtr oldPort;
UniversalProcPtr oldFrontWindow = GetToolboxTrapAddress(_FrontWindow);
DialogRef aDialog;
Boolean eventHasBeenGobbled = false;
short aDialogItem = 0;
short oldWindowKind;
// Don’t snarf keypresses meant for menus
if ((theEvent->what == keyDown) && (theEvent->modifiers & cmdKey))
return false;
GetPort(&oldPort);
SetGrafPortOfDialog ( GetDialogRef ());
// Patch in our version of FrontWindow so that IsDialogEvent will do the right
// thing. DialogManager should check both frontmost floating and frontmost
// non-floating windows, however we don’t support floating dialogs.
SetToolboxTrapAddress(FrontWindowPatchUPP, _FrontWindow);
// Jam the windowKind of our dialog window back to dialogKind so that the
// Dialog Manager can recognize our window as a dialog window.
oldWindowKind = GetWindowKind(fWindow);
SetWindowKind(fWindow, dialogKind);
if (IsDialogEvent(theEvent))
{
// It’s definitely a dialog event, so let the Dialog Manager figure things out.
//
// We first let StdFilterProc have a crack at it so that the default
// and cancel buttons are properly processed (as well as automagic text
// cursor tracking).
// If StdFilterProc didn’t find anything to do, go ahead and call
// DialogSelect to figure out if the user did anything important.
// Isn’t this alot easier than what Inside Mac says to do?
eventHasBeenGobbled = StdFilterProc( GetDialogRef (),theEvent,&aDialogItem);
// Give the window a chance to pre-process the event
// This is useful for people who want to implement read-only text items (for example)
if (eventHasBeenGobbled == false)
eventHasBeenGobbled = this->FilterDialogEvent ( theEvent, &aDialogItem );
// Let the dialog manager deal with the event
if (eventHasBeenGobbled == false)
eventHasBeenGobbled = DialogSelect(theEvent,&aDialog,&aDialogItem);
}
// Restore the windowKind
SetWindowKind(fWindow, oldWindowKind);
// Put FrontWindow back the way it really belongs
SetToolboxTrapAddress((UniversalProcPtr) oldFrontWindow, _FrontWindow);
if (eventHasBeenGobbled)
{
this->ItemHit(aDialogItem); // Call user’s method to deal with a hit
eventHasBeenGobbled = true;
}
SetPort(oldPort);
return eventHasBeenGobbled;
}
/*****************************************************************************/
Boolean TDialogWindow::FilterDialogEvent(EventRecord */*theEvent*/, short *itemHit )
{
*itemHit = 0;
return false; // Event not handled
}
/*****************************************************************************/
void TDialogWindow::Activate(Boolean activating)
{
EventRecord fakeEvent;
/* (De)activates are NOT automagically handled because our floating
* windows prevent real activate events from ever being generated
* for any non-floaters windows.
*
* Our strategy is to fool the dialog manager into thinking that
* things are still fine by passing it a fake (de)activate event.
*
* Luckily, we don’t have to patch FrontWindow to make DialogSelect
* work for activate and update events.
*/
OSEventAvail(0, &fakeEvent); // Get an intialized, but otherwise empty event record
fakeEvent.what = activateEvt;
fakeEvent.message = (unsigned long) GetDialogRef ();
if (activating)
fakeEvent.modifiers |= activeFlag;
else
fakeEvent.modifiers &= ~activeFlag;
// Pass event on to DialogSelect
DialogRef aDialog;
short aDialogItem;
(void) DialogSelect(&fakeEvent,&aDialog,&aDialogItem);
}
/*****************************************************************************/
void TDialogWindow::Draw(void)
{
// Automagically handled by Dialog Manager when we are
// the frontmost window, but not at other times because
// we only set the windowKind to dialogKind inside our
// EventFilter (which is only active when we are frontmost).
RgnHandle update = NewRgn ();
GetWindowUpdateRgn ( fWindow, update );
UpdateDialog ( GetDialogRef (), update );
DisposeRgn ( update );
}
/*****************************************************************************/
void TDialogWindow::Click(EventRecord * /* anEvent */)
{
/* The only time this method is called is to handle a click
* when the dialog window isn’t frontmost. All other times,
* DialogSelect will do everything for us.
*
* If our dialog contains useritems with the ability to
* be the source of a drag we’d need to start drag tracking
* in here.
*/
this->Select();
}
/*****************************************************************************/
void TDialogWindow::AdjustMenusBeforeMenuSelection(void)
{
TEHandle teh = GetDialogTextEdit ( GetDialogRef() );
Boolean validSelection = teh != NULL && ( (*teh)->selStart != (*teh)->selEnd );
gMenuBar->EnableCommand ( cCut, validSelection );
gMenuBar->EnableCommand ( cCopy, validSelection );
gMenuBar->EnableCommand ( cPaste, true ); // we really should check the scrap
gMenuBar->EnableCommand ( cClear, validSelection );
gMenuBar->EnableCommand ( cSelectAll, teh != NULL );
}
/*****************************************************************************/
Boolean TDialogWindow::DoCommand(CommandID command)
{
DialogRef theDialog = GetDialogRef ();
switch (command)
{
case cCut:
DialogCut(theDialog);
return true;
case cCopy:
DialogCopy(theDialog);
return true;
case cPaste:
DialogPaste(theDialog);
return true;
case cClear:
DialogDelete(theDialog);
return true;
case cSelectAll:
SelectDialogItemText ( theDialog, GetDialogKeyboardFocusItem ( theDialog ), 0, 32767 );
return true;
}
// If we don't handle it, then let the super-class handle it
return TWindow::DoCommand ( command );
}